package com.crane.framework.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.crane.framework.entity.Role;
import com.crane.framework.entity.UserRole;
import com.crane.framework.service.IRoleService;
import com.crane.framework.service.IUserRoleService;
import com.crane.framework.mapper.UserRoleMapper;
import com.crane.framework.utils.CommonUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole>
    implements IUserRoleService {

  @Resource private IRoleService roleService;

  @Override
  public List<Role> getRoleListByUserId(String userId) {
    List<UserRole> userRoleList = this.lambdaQuery().eq(UserRole::getUserId, userId).list();
    if (CommonUtil.isNullOrEmpty(userRoleList)) {
      return null;
    }

    List<String> roleIdList = userRoleList.stream().map(UserRole::getRoleId).toList();

    return roleService.lambdaQuery().in(Role::getId, roleIdList).list();
  }

  @Override
  public Map<String, List<String>> getRoleSignMapByUserId(List<String> userIdList) {
    return getRoleMapByUserId(userIdList, Role::getRoleSign);
  }

  @Override
  public Map<String, List<String>> getRoleNameMapByUserId(List<String> userIdList) {
    return getRoleMapByUserId(userIdList, Role::getRoleName);
  }

  @Override
  public void removeByUserId(String userId) {
    this.remove(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getUserId, userId));
  }

  private Map<String, List<String>> getRoleMapByUserId(
      List<String> userIdList, Function<Role, String> roleFunction) {
    List<UserRole> userRoleList = this.lambdaQuery().in(UserRole::getUserId, userIdList).list();
    if (CommonUtil.isNullOrEmpty(userRoleList)) {
      return null;
    }

    List<Role> roleList = roleService.list();

    if (CommonUtil.isNullOrEmpty(roleList)) {
      return null;
    }

    Map<String, Role> roleMap =
        roleList.stream().collect(Collectors.toMap(Role::getId, Function.identity()));

    Map<String, List<UserRole>> listMap =
        userRoleList.stream().collect(Collectors.groupingBy(UserRole::getUserId));

    Map<String, List<String>> map = new HashMap<>();
    listMap.forEach(
        (key, value) -> {
          List<String> roleListData = new ArrayList<>();
          value.forEach(
              userRole -> {
                Role role = roleMap.get(userRole.getRoleId());
                if (CommonUtil.notNullOrEmpty(role)) {
                  roleListData.add(roleFunction.apply(role));
                }
              });
          map.put(key, roleListData);
        });

    return map;
  }
}
